/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package projet_compressionimage;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import static projet_compressionimage.CompressionImage.CompresserArbre;
import static projet_compressionimage.CompressionImage.MAX_DISTANCE_COULEUR;
import static projet_compressionimage.CompressionImage.TransformerEnArbre;
import static projet_compressionimage.CompressionImage.TransformerEnImage;

/**
 *
 * @author Colin
 */
public class ArbreQuadratique {
    //Vars statiques
    public static int size2nMax=2048;
    
    //Attributs
    private Noeud premierNoeud; //premier noeud de l'arbre
    private int imageWidth;     //largeur de l'image d'origine
    private int imageHeight;    //hauteur de l'image d'origine
    private int size2n;         // Taille de la matrice carree redimensionnée
    private int hauteurDorigine;// hauteur de l'arbre avant compressions
    private int imageType;
    private BufferedImage image;
    
    ArbreQuadratique(BufferedImage image) {
         premierNoeud = new NoeudCompose("0");
         imageWidth=image.getWidth();
         imageHeight=image.getHeight();
         imageType=image.getType();
         hauteurDorigine=0;
         this.image=image;
    }

    public void quadripartition(BufferedImage image) {
        //Former une image [2^n par 2^n] qui est >= à l'image d'origine
        size2n = foundSize2n(image);
        System.out.println("Redimensionnement matrice carré :"+size2n+"*"+size2n+" px");
        

         
        if(size2n != imageWidth || size2n != imageWidth){
            BufferedImage image2n= new BufferedImage(size2n, size2n, image.getType());
            image2n=copyImageInto(image2n,image);
            hauteurDorigine=calculeHauteur(size2n);
            premierNoeud.quadripartition(image2n);
        }else{
            hauteurDorigine=calculeHauteur(imageWidth);
            premierNoeud.quadripartition(image);
        }
    }
    public static void CompresserGrandeImage(BufferedImage image,int nbCompressions,int nbdivisionsResolution, int indicateurDiffMaxCouleurs){
                        int size2N=ArbreQuadratique.foundSize2n(image);
                        BufferedImage image2n= new BufferedImage(size2N, size2N, image.getType());
                        image2n=ArbreQuadratique.copyImageInto(image2n,image);
                        // trouver le nombre de morceaux à découper.
                        //while(){
                            // découpage le morceau img de image
                            BufferedImage img = image2n.getSubimage(0, 0, size2nMax, size2nMax);
                            ArbreQuadratique arbre = TransformerEnArbre(img);
                            arbre=CompresserArbre(arbre,nbCompressions,nbdivisionsResolution,indicateurDiffMaxCouleurs);
                            System.out.println("Fabrication de la nouvelle image");
                            BufferedImage nouvImage=TransformerEnImage(arbre);
                            // recoller l'image au bon endroit dans l'image imageModifie
                        //}

    }
    
    public void compression(int nbCompression, int indicateurDiffMaxCouleurs){
        int compteurNiveaux= this.hauteurDorigine-nbCompression;
        premierNoeud.compression(compteurNiveaux, indicateurDiffMaxCouleurs);
    }
    
    public void diviserResolution(int nbCompression){
        this.hauteurDorigine = hauteurDorigine-nbCompression;
        this.size2n = (int)(this.size2n/Math.pow(2, nbCompression));
        this.imageHeight=(int)(this.imageHeight/Math.pow(2, nbCompression));
        this.imageWidth=(int)(this.imageWidth/Math.pow(2, nbCompression));
        System.out.println("size2n:"+size2n);
        System.out.println("imageHeight:"+imageHeight);
        System.out.println("imageWidth:"+imageWidth);

    }
    public BufferedImage reconstitutionImage(){
        BufferedImage image2n= new BufferedImage(size2n, size2n, imageType);
        image2n=premierNoeud.reconstitutionImage(this.size2n, image2n,0,0);
        return image2n.getSubimage(0, 0, imageWidth, imageHeight);
    }
    
    public static int foundSize2n(BufferedImage img) {
        int mult=1;
        while(img.getWidth()>mult || img.getHeight()>mult){
            mult=mult*2;
        }
        return mult;
    }
    private int calculeHauteur(int size) {
        int somme=1;
        while(size>2){
            size=size/2;
            somme++;
        }
        return somme;
    }
    
    public static BufferedImage copyImageInto(BufferedImage image2n, BufferedImage image) {
       for(int i=0;i<image.getWidth();i++){
            for(int j=0;j<image.getHeight();j++){
                image2n.setRGB(i, j, image.getRGB(i, j));
            }
        }
        return image2n;
    }
    
    
    /*Affichage*/
    @Override
    public String toString() {
        return "ArbreQuadratique{ hauteur=" +hauteurDorigine+ ", imageWidth=" + imageWidth + ", imageHeight=" + imageHeight + "\npremierNoeud=" + premierNoeud + '}';
    }


    
    /*GETTERS & SETTERS*/
    public Noeud getPremierNoeud() {
        return premierNoeud;
    }

    public void setPremierNoeud(Noeud premierNoeud) {
        this.premierNoeud = premierNoeud;
    }

    public int getImageWidth() {
        return imageWidth;
    }

    public void setImageWidth(int imageWidth) {
        this.imageWidth = imageWidth;
    }

    public int getImageHeight() {
        return imageHeight;
    }

    public void setImageHeight(int imageHeight) {
        this.imageHeight = imageHeight;
    }

    public int getHauteurDorigine() {
        return hauteurDorigine;
    }

    public void setHauteurDorigine(int hauteurDorigine) {
        this.hauteurDorigine = hauteurDorigine;
    }

    

    
    
    
    
    
}
